package MainApplication;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import java.io.*;

import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;


import org.jdom.*;
import org.jdom.input.SAXBuilder;

import Connect.Connection;
import MySQL.MySQLAccess;
import Node.Gateway;
import Node.Node;
import Node.ResolveAddres;

public class Timers {
	private Timer timerNodes;
	private Timer timerMail;
	private Timer timerFetchToDB;
	
	private String defaultServer;
	private Vector<Node> nodes;
	
	private static final String rdfURL = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
    private static final String resURL = "urn:sensei:rai";

	public Timers(String defaultServer, int nodeSeconds, int mailSeconds, int otherDBSeconds){
		nodes = new Vector<Node>();
		
		this.defaultServer = new String();
		this.defaultServer = defaultServer;
		
		timerNodes = new Timer();
		timerNodes.schedule(new GetNodesTask(), 0, nodeSeconds * 1000);
		
		timerMail = new Timer();
		timerMail.schedule(new VerifyMailTask(), 3000, mailSeconds * 1000);
		
		timerFetchToDB = new Timer();
		timerFetchToDB.schedule(new FetchToDB(), 4000, otherDBSeconds * 1000);
	}
	
	class FetchToDB extends TimerTask{
		public void run(){
			System.out.println("nothing yet");
			
			for (int i=0; i < nodes.size(); i++){
				System.out.println(nodes.get(i).toString());
				
				MySQLAccess dao = new MySQLAccess(nodes.get(i));
				try {
					dao.insertIntoTheOtherDatabase();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	class VerifyMailTask extends TimerTask{
		public void run(){
			System.out.println("Checking Mail!");
			MySQLAccess daoRegUsers = new MySQLAccess("localhost");
			
			try{
				ArrayList<RegisteredUser> arrayUsers = daoRegUsers.readRegisteredUsers();

				// Iau la rand fiecare user din baza de date RegisteredUsers
				// si fiecare nod
				// si verific daca nu cumva s-a trecut peste sau sub valoarea de prag
				for (int i = 0; i < arrayUsers.size(); i++){
					for (int j = 0; j < nodes.size(); j++){ //ugly code!
						//valorile peste prag
						if (arrayUsers.get(i).temp_threshold != null && !arrayUsers.get(i).temp_threshold.isEmpty())
							if (Double.parseDouble(nodes.get(j).getTemp()) > Double.parseDouble(arrayUsers.get(i).temp_threshold)){
								System.out.println(arrayUsers.get(i).getMail());
								new SendMail(arrayUsers.get(i).getMail(), "Temperatura", true);
								System.out.println("mail!");
							}
						if (arrayUsers.get(i).light_threshold != null && !arrayUsers.get(i).light_threshold.isEmpty())
							if (Double.parseDouble(nodes.get(j).getLight()) > Double.parseDouble(arrayUsers.get(i).light_threshold)){
								new SendMail(arrayUsers.get(i).getMail(), "Lumina", true);
							}
						if (arrayUsers.get(i).current_threshold != null && !arrayUsers.get(i).current_threshold.isEmpty())
							if (Double.parseDouble(nodes.get(j).getCurrent()) > Double.parseDouble(arrayUsers.get(i).current_threshold)){
								new SendMail(arrayUsers.get(i).getMail(), "Curent", true);
							}
						if (arrayUsers.get(i).battery_threshold != null && !arrayUsers.get(i).battery_threshold.isEmpty())
							if (Double.parseDouble(nodes.get(j).getBattery()) > Double.parseDouble(arrayUsers.get(i).battery_threshold)){
								new SendMail(arrayUsers.get(i).getMail(), "Baterie", true);
							}
					}
				}
			}
			catch (Exception e){
				e.printStackTrace();
			}
		}
	}
	
	class GetNodesTask extends TimerTask{
		public void run(){
					
			Document response = Connection.connect(defaultServer);
			
			Namespace rdf = Namespace.getNamespace(rdfURL);
			Namespace res = Namespace.getNamespace(resURL);

			Element root = response.getRootElement();
			Gateway gw = new Gateway(root, res, rdf);
			System.out.println(gw.toString());

			List<Element> allElements = root.getChildren("Seq", rdf);
			List<Element> sensorsList = allElements.get(0).getChildren("Plugin", res);
			List<Element> sensorsInfo = sensorsList.get(1).getChildren();
			System.out.println(sensorsInfo.size());

			final String URL = gw.getURL();
			System.out.println(URL);

			Iterator<Element> it = sensorsInfo.iterator();
			
			Vector<String> node_ids = new Vector<String>();
			Vector<String> node_temp = new Vector<String>();
			Vector<String> node_light = new Vector<String>();
			Vector<String> node_current = new Vector<String>();
			Vector<String> node_battery = new Vector<String>();
			
			while(it.hasNext()){
				Element element = (Element) it.next();
				String value = element.getAttributeValue("hasURL", res);

				value = value.replace(URL, "");
				//System.out.println(modifiedValue);

				if (value.contains("-") && !value.contains("/")){
					node_ids.add(value);
				}
				else if (value.contains("-") && value.contains("s/temp")){
					node_temp.add(value);
				}
				else if (value.contains("-") && value.contains("s/light")){
					node_light.add(value);
				}
				else if (value.contains("-") && value.contains("p/battery")){
					node_battery.add(value);
				}
				else if (value.contains("-") && value.contains("p/current")){
					node_current.add(value);
				}
			}
			
			nodes.clear();
			
			for (int i=0; i < node_ids.size(); i++){
				ResolveAddres raTemp = new ResolveAddres(rdfURL, resURL, URL + node_temp.get(i));
				ResolveAddres raLight = new ResolveAddres(rdfURL, resURL, URL + node_light.get(i));
				ResolveAddres raBattery = new ResolveAddres(rdfURL, resURL, URL + node_battery.get(i));
				ResolveAddres raCurrent = new ResolveAddres(rdfURL, resURL, URL + node_current.get(i));
				
				//System.out.println(raTemp.getValues());
				
				Node n = new Node(node_ids.get(i), 0);
				n.setTemp(raTemp.getValues());
				n.setLight(raLight.getValues());
				n.setBattery(raBattery.getValues());
				n.setCurrent(raCurrent.getValues());
				
				nodes.add(n);
			}
			
			MySQLAccess deleteDB = new MySQLAccess();
			deleteDB.deleteAllEntries();
			
			for (int i=0; i < nodes.size(); i++){
				System.out.println(nodes.get(i).toString());
				
				MySQLAccess dao = new MySQLAccess(nodes.get(i));
				try {
					dao.insertIntoDatabase();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
}
